#ifndef DATA_BODY_H
#define DATA_BODY_H

#include "Common/Geometry/Circle.h"
#include "Data/Objects/PolygonShape.h"

namespace data {

	class Body
	{
	public:
		Body(
			float mass,
			float inertia,
			float friction,
			float restitution ) :
			m_mass( mass ),
			m_inertia( inertia ),
			m_friction( friction ),
			m_restitution( restitution )
		{
			m_circles = new cmn::Vector<cmn::Circle>();
			m_polygons = new cmn::Vector<PolygonShape>();
		}

		Body( const Body& body ) :
			m_mass( body.GetMass() ),
			m_inertia( body.GetInertia() ),
			m_friction( body.GetFriction() ),
			m_restitution( body.GetRestitution() )
		{
			m_circles = new cmn::Vector<cmn::Circle> ( body.GetCircles() );
			m_polygons = new cmn::Vector<PolygonShape> ( body.GetPolygons() );
		}

		~Body() {
			delete m_circles;
			delete m_polygons;
		}

		inline const float GetMass() const { return m_mass; }
		inline void SetMass( float mass ) { m_mass = mass; }

		inline const float GetInertia() const { return m_inertia; }
		inline void SetInertia( float inertia ) { m_inertia = inertia; }

		inline const float GetFriction() const { return m_friction; }
		inline void SetFriction( float friction ) { m_friction = friction; }

		inline const float GetRestitution() const { return m_restitution; }
		inline void SetRestitution( float restitution ) { m_restitution = restitution; }

		inline void AddCircle( const cmn::Circle& circle ) { m_circles->Add( circle ); }
		inline void RemoveCircle( const cmn::Circle& circle ) { m_circles->Remove( circle ); }
		inline const cmn::IIterable<cmn::Circle>* GetCircles() const { return m_circles; }

		inline void AddPolygon( const PolygonShape& polygon ) { m_polygons->Add( polygon ); }
		inline void RemovePolygon( const PolygonShape& polygon ) { m_polygons->Remove( polygon ); }
		inline const cmn::IIterable<PolygonShape>* GetPolygons() const { return m_polygons; }

	private:
		float m_mass;
		float m_inertia;
		float m_friction;
		float m_restitution;

		cmn::Vector<cmn::Circle>* m_circles;
		cmn::Vector<PolygonShape>* m_polygons;
	};

	inline bool operator == ( const Body& a, const Body& b ) {
		if( a.GetMass() != b.GetMass() ) return false;
		if( a.GetInertia() != b.GetInertia() ) return false;
		if( a.GetFriction() != b.GetFriction() ) return false;
		if( a.GetRestitution() != b.GetRestitution() ) return false;

		if( !IterablesAreEqual( a.GetCircles(), b.GetCircles() ) ) return false;
		if( !IterablesAreEqual( a.GetPolygons(), b.GetPolygons() ) ) return false;

		return true;
	}

	inline bool operator != ( const Body& a, const Body& b ) {
		return !( a == b );
	}
}

#endif
